// VBlockBuilder.cpp
// Implement class VBlockBuilder

#include "crossbit/VBlockBuilder.h"
#include "crossbit/VBlock.h"

using namespace crossbit;

    VBlockBuilder::VBlockBuilder()
:bb_vblock(NULL)
{
	this->VBlock_Counter=0;
}

VBlockBuilder::~VBlockBuilder()
{
    if (bb_vblock)
        delete bb_vblock;
}

// Default behavior: instantiate VBlock object
void VBlockBuilder::getReady(XTMemAddr pc)
{
    assert(bb_vblock == NULL);	// make sure block_ has been packed and delivered to user
    bb_vblock = new VBlock(pc);
    bb_vreg = 1;
}

// Added by Zhang Yichao for CFG
void VBlockBuilder::getReady(XTMemAddr enter_pc, XTMemAddr next_pc)
{
    assert(bb_vblock == NULL);
    bb_vblock = new VBlock(enter_pc, next_pc);
    bb_vreg = 1;
}

// Default behavior: append the VInstruction into VBlock as long as it doesn't end
void VBlockBuilder::add(VInst *inst)
{
    bb_vblock->push_back(inst);
}

// Default behavior: never ends
bool VBlockBuilder::isEnd()
{
    return false;
}

// Added by Zhang Yichao for CFG
bool VBlockBuilder::isEnd(XTMemAddr pc)
{
    if(pc >= bb_vblock->nextSPC() || pc < bb_vblock->enterSPC())
        return true;
    else
        return false;
}

// Default behavior: return the VBlock, and nullify the internal handler
VBlock *VBlockBuilder::wrapUp(XTMemAddr spc)
{//MODIFIED BY ZHUNAN
    VBlock *res = bb_vblock;
    bb_vblock = NULL;
    res->setVbNextSpc( spc );

	this->VBlock_Counter++;
	res->Set_VBlock_ID(VBlock_Counter);
/*	if (res->Get_VBlock_ID()==361)
	{
		printf("%x\n",res->enterSPC());	
	}*/

    return res;
}
